﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace daStaticAnalyser.Analysers
{
    using daStaticAnalyser.Analysers;
    using daStaticAnalyser;
    using daBase.Objects;
    using daBase.Analyser;
    using daSyntaxAnalyser;
    using daSyntaxAnalyser.SyntaxTree;

    [AnalyserDefaultSettings("Количество \"логических\" строк кода", "test", 0, "test")]
    class LSIAnalyzator : BaseStaticAnalyser
    {
        bool CaseOpSet = true, TryOpSet = true, RepeatOpSet = true, ExeptOpSet = true, ForOpSet = true,
             TestOpSet = true, WhileOpSet = true, AssignOpSet = true, CallOpSet = true, GotoOpSet = true, RaiseOpSet = true; 

        [Category("Особые")]
        [DisplayName("Оператор Case")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsCaseOpSet { get { return CaseOpSet; } set { CaseOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор Try")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsTryOpSet { get { return TryOpSet; } set { TryOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор Repeat")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsRepeatOpSet { get { return RepeatOpSet; } set { RepeatOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор Exept")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsExeptOpSet { get { return ExeptOpSet; } set { ExeptOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор For")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsForOpSet { get { return ForOpSet; } set { ForOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор Test")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsTestOpSet { get { return TestOpSet; } set { TestOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор While")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsWhileOpSet { get { return WhileOpSet; } set { WhileOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор присваивания")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsAssignOpSet { get { return AssignOpSet; } set { AssignOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор вызова подпрограммы")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsCallOpSet { get { return CallOpSet; } set { CallOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор GOTO")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsGotoOpSet { get { return GotoOpSet; } set { GotoOpSet = value; } }

        [Category("Особые")]
        [DisplayName("Оператор Raise")]
        [Description("Если флаг не установлен, то оператор не учитывается при подсчёте метрики.")]
        public bool IsRaiseOpSet { get { return RaiseOpSet; } set { RaiseOpSet = value; } }

        private int CalculateCountOperators(ISyntaxTreeElement Element)
        {
            if (Element == null)
                return 0;
            int result = 0;
            if (((Element is CaseStatementElement) && CaseOpSet) ||
                ((Element is TryStatementElement) && TryOpSet) ||
                ((Element is RepeatStatementElement) && RepeatOpSet) ||
                ((Element is ExceptOnStatementElement) && ExeptOpSet) ||
                ((Element is ForStatementElement) && ForOpSet) ||
                ((Element is TestStatementElement) && TestOpSet) ||
                ((Element is WhileStatementElement) && WhileOpSet) ||
                ((Element is AssignmentElement) && AssignOpSet) ||
                ((Element is VariableStatementElement) && CallOpSet) ||
                ((Element is RaiseStatementElement) && RaiseOpSet) ||
                ((Element is GotoStatementElement) && GotoOpSet))
            {
                result = 1;
            }
            foreach (ISyntaxTreeElement element in Element)
                result += CalculateCountOperators(element);
            return result;
        }

        protected override void DoAnalyse(SyntaxTreeArgs e)
        {
            String MethodName = "";
            if (CheckMethod_GetName(e, out MethodName))
            {
                int LSI = CalculateCountOperators((e.Element as OuterMethodElement).Body);
                AddMetric("Количество операторов",
                            LSI,
                            MethodName,
                            e.Element.StartInfo.File,
                            e.Element.StartInfo.Line); 
            }
        }

    }
}
